package thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ABCPrint {
    private Lock lock=new ReentrantLock();
    private Condition aCondition=lock.newCondition();
    private Condition bCondition=lock.newCondition();
    private Condition cCondition=lock.newCondition();
    private String thFlag="A";

    public static void main(String[] args) {
        ABCPrint test=new ABCPrint();
        Thread t1=new Thread(test.new Task(test.aCondition,"A"));
        Thread t2=new Thread(test.new Task(test.bCondition,"B"));
        Thread t3=new Thread(test.new Task(test.cCondition,"C"));
        t1.start();
        t2.start();
        t3.start();


    }

    class Task implements Runnable{
        private Condition condition;
        private String flag;



        public Task(Condition condition,String flag) {
            this.condition=condition;
            this.flag=flag;


        }

        @Override
        public void run() {
            try {
                lock.lock();
                for(int i=0;i<10;i++){
                    if(flag.equals("A")){

                        while(!thFlag.equals("A")){
                            aCondition.await();
                        }
                        System.out.println("A");
                        thFlag="B";
                        bCondition.signal();
                    }else if(flag.equals("B")){

                        while(!thFlag.equals("B")){
                            bCondition.await();
                        }
                        System.out.println("B");
                        thFlag="C";
                        cCondition.signal();
                    }else if(flag.equals("C")){
                        while(!thFlag.equals("C")){
                            cCondition.await();
                        }
                        System.out.println("C");
                        thFlag="A";
                        aCondition.signal();
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }
}
